﻿using System;
using System.Collections;
using System.Collections.Specialized;
using System.Data;
using System.Data.SqlClient;
using System.Reflection;
using System.Text;
using NHibernate;
using NHibernate.Cfg;
using NHibernate.SqlCommand;
using VitCode.Castle.Entities;
using VitCode.Castle.Helper;

namespace VitCode.Castle.DataAccess
{
    /// <summary>
    /// 持久化层操作及数据访问核心对象
    /// </summary>
    public class BaseDataAccess
    {
        /// <summary>
        /// 此为NHibernate的关键设置信息
        /// </summary>
        private const string CurrentSessionKey = "nhibernate.current_session";
        private static readonly ISessionFactory m_SessionFactory;
        public static string ERR_OBJ_NAME_FG = "##";
        public static string ERR_PRO_NAME_FG = "||";
        public static string LOGIC_DELETE = "邏輯刪除", REAL_DELETE = "物理刪除", REVERT = "還原";
        private ISession m_Session;
        private ITransaction m_Transaction;
        public static string KEY_VAL_FG = "|-|";

        static BaseDataAccess()
        {
            try
            { 
                m_SessionFactory = new Configuration().Configure().BuildSessionFactory();
            }
            catch(Exception ex)
            {
                throw ex;
            }
           
        }

        /// <summary>
        /// 獲取Session,無論連接是否關閉 Session是否存在
        /// Session一定會被獲取
        /// </summary>
        public virtual ISession Session
        {
            get
            {
                if (m_Session == null || !m_Session.IsOpen)
                {
                    m_Session = GetCurrentSession();
                }
                if (!m_Session.IsConnected)
                    m_Session.Reconnect();
                return m_Session;
            }

            set { m_Session = value; }
        }

        /// <summary>
        /// 獲取新的資料庫連接，不與當前session連接相同
        /// </summary>
        /// <returns></returns>
        public static ISession GetNewSession()
        {
            return m_SessionFactory.OpenSession();
        }

        /// <summary>
        /// 获取当天Session
        /// </summary>
        /// <returns></returns>
        public static ISession GetCurrentSession()
        {
            var context = new GenericContext();
            var currentSession = context as ISession;

            if (currentSession == null)
            {
                currentSession = m_SessionFactory.OpenSession();
                context[CurrentSessionKey] = currentSession;
            }

            return currentSession;
        }

        /// <summary>
        /// 关闭Session
        /// </summary>
        public virtual void CloseSession()
        {
            var context = new GenericContext();
            var currentSession = context[CurrentSessionKey] as ISession;
            if (currentSession == null || currentSession.IsOpen == false)
            {
                // No current session
                return;
            }

            currentSession.Close();
        }

        /// <summary>
        /// 关闭Session工厂
        /// </summary>
        public static void CloseSessionFactory()
        {
            if (m_SessionFactory != null)
            {
                m_SessionFactory.Close();
            }
        }

        /// <summary>
        /// 開始事務,用哪個物件打開，必須用相同的物件關閉事務
        /// </summary>
        public virtual void BeginTransaction()
        {
            m_Transaction = Session.BeginTransaction();
        }

        /// <summary>
        /// 提交事務,用哪個物件打開，必須用相同物件進行提交
        /// </summary>
        public virtual void Commit()
        {
            if (m_Transaction == null)
                throw new AccessViolationException("需要打開Transaction");
            m_Transaction.Commit();
        }

        /// <summary>
        /// 回滾事務，用哪個物件打開，必須用相同的物件進行提交
        /// </summary>
        public virtual void RollBack()
        {
            if (m_Transaction == null)
                throw new AccessViolationException("需要打開Transaction");
            m_Transaction.Rollback();
        }

        /// <summary>
        /// 获取某对象在系统中所有的实例
        /// </summary>
        /// <param name="className">对象名称</param>
        /// <returns>对象实例集合</returns>
        public IList GetObjectList(string className)
        {
            var sb = new StringBuilder("FROM " + className + " o ");

            return Session.CreateQuery(sb.ToString()).List();
        }

        /// <summary>
        /// 获取相符对象的系统实例
        /// </summary>
        /// <param name="className">对象名称</param>
        /// <param name="keyColNameValue">条件过滤键值对[Key=属性名称,Value=属性值],键值对之前是逻辑And的操作符</param>
        /// <returns></returns>
        public IList GetObjectList(string className, NameValueCollection keyColNameValue)
        {
            var sb = new StringBuilder("FROM " + className + " o ");
            StringBuilder stringBuilder = sb;
            for (int i = 0; i < keyColNameValue.Count; i++)
            {
                if (i == 0)
                    stringBuilder.Append(" WHERE ");
                else
                    stringBuilder.Append(" AND ");
                stringBuilder.Append(" o." + keyColNameValue.GetKey(i) + "='" + keyColNameValue.Get(i) + "' ");
            }
            return Session.CreateQuery(stringBuilder.ToString()).List();
        }

        /// <summary>
        /// 根據Id取對象
        /// </summary>
        /// <param name="className">類名</param>
        /// <param name="idVal">Id值</param>
        /// <param name="isIgnoreRepeat">是否忽略多個物件存在於系統</param>
        /// <returns>物件</returns>
        public object GetSingleObjectById(string className, string idVal, bool isIgnoreRepeat)
        {
            return GetSingleObjectByProVal(className, "Id", idVal, isIgnoreRepeat);
        }

        /// <summary>
        /// 根據Id取對象(默認不忽略多個物件同一ID的資料異常)
        /// </summary>
        /// <param name="className">類名</param>
        /// <param name="idVal">id值</param>
        /// <returns>物件</returns>
        public object GetSingleObjectById(string className, string idVal)
        {
            return GetSingleObjectById(className, idVal, false);
        }

        public object GetSingleObjectByProVal(string className, string proName, string proVal, bool isIgnoreRepeat)
        {
            IList lstObjs = GetObjectList(className, proName, proVal);
            if (lstObjs == null || lstObjs.Count == 0)
                throw new ArgumentNullException("找不到" + proName + "為\"" + proVal + "\"的\"" + className + "\"");
            else if (lstObjs.Count > 1 && isIgnoreRepeat)
                throw new ArgumentException(proName + "為\"" + proVal + "\"的\"" + className + "\"物件存在一個以上,資料異常");
            else
                return lstObjs[0];
        }

        /// <summary>
        /// 获取指定单一对象实例
        /// </summary>
        /// <param name="className">对象名称</param>
        /// <param name="proName">属性名称,这里一定是业务唯一主键才可能反回单一对象实例</param>
        /// <param name="proVal">属性值</param>
        /// <returns>指定单一对象实例</returns>
        public object GetSingleObjectByProVal(string className, string proName, string proVal)
        {
            return GetSingleObjectByProVal(className, proName, proVal, false);
        }

        /// <summary>
        /// 获取指定的对象实例集合
        /// </summary>
        /// <param name="className">对象名称</param>
        /// <param name="keyProName">对象查询属性名称</param>
        /// <param name="keyProVal">对象查询属性值</param>
        /// <returns>指定的对象实例集合</returns>
        public IList GetObjectList(string className, string keyProName, string keyProVal)
        {
            var nvc = new NameValueCollection {{keyProName, keyProVal}};
            return GetObjectList(className, nvc);
        }

        /// <summary>
        /// 获取指定范围内的对象实例集合
        /// </summary>
        /// <param name="className">对象名称</param>
        /// <param name="keyColNameValues">对象过滤条件键值对数组,[Key=属性名称,Value=属性值],键值对之间为[And]逻辑操作符,数组之间为[Or]逻辑操作符</param>
        /// <returns>指定范围内的对象实例集合</returns>
        public IList GetObjectList(string className, NameValueCollection[] keyColNameValues)
        {
            var sb = new StringBuilder("FROM " + className + " o ");
            bool isFirst = true;
            foreach (NameValueCollection nvc in keyColNameValues)
            {
                if (isFirst)
                {
                    sb.Append(" WHERE ");
                    isFirst = false;
                }
                else
                    sb.Append(" OR ");

                for (int i = 0; i < nvc.Count; i++)
                {
                    if (i == 0)
                        sb.Append(" ( ");
                    else
                        sb.Append(" AND ");
                    sb.Append(" o." + nvc.GetKey(i) + "='" + nvc.Get(i) + "' ");
                    if (i == nvc.Count - 1)
                        sb.Append(" ) ");
                }
            }

            return Session.CreateQuery(sb.ToString()).List();
        }


        /// <summary>
        /// 插入Update操作，返回影響的行數
        /// </summary>
        /// <param name="procedureName"></param>
        /// <returns></returns>
        public int ExecuteCmdByProcedureName(string procedureName)
        {
            
            IDbCommand command = Session.Connection.CreateCommand();
            if (Session.Transaction != null)
                Session.Transaction.Enlist(command);

            command.CommandType = CommandType.StoredProcedure;
            command.CommandText = procedureName;
           
            int access = command.ExecuteNonQuery();
            return access;
        }


        /// <summary>
        /// 插入Update操作，返回影響的行數
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        public int ExecuteCmd(string sql)
        {
            IDbCommand command = Session.Connection.CreateCommand();
            if (Session.Transaction != null)
                Session.Transaction.Enlist(command);
            command.CommandText = sql;
            int access = command.ExecuteNonQuery();
            return access;
        }


        /// <summary>
        /// 執行存儲過程，返回第一行第一列的值  
        /// </summary>
        /// <param name="procedureName">存儲過程名稱</param>
        /// <returns></returns>
        public string GetValueRunProc(string procedureName)
        {

            IDbCommand comm = Session.Connection.CreateCommand();
            if (Session.Transaction != null)
                Session.Transaction.Enlist(comm);

            comm.CommandText = procedureName;
            comm.CommandType = CommandType.StoredProcedure;
            var value = (string)comm.ExecuteScalar();
            return value;
        }

        /// <summary>
        /// 執行帶參數的存儲過程，返回第一行第一列的值  
        /// </summary>
        /// <param name="procedureName">存儲過程名稱</param>
        /// <param name="prams">由參數值組成的陣列</param>
        /// <returns></returns>
        public string GetValueRunProc(string procedureName, SqlParameter[] prams)
        {
            IDbCommand comm = Session.Connection.CreateCommand();
            if (Session.Transaction != null)
                Session.Transaction.Enlist(comm);
            foreach (var pram in prams)
            {
                comm.Parameters.Add(pram);
            }

            comm.CommandText = procedureName;
            comm.CommandType = CommandType.StoredProcedure;
            var value = (string)comm.ExecuteScalar();
            return value;
        }


        /// <summary>
        /// 获取查询返回的DataTable
        /// </summary>
        /// <param name="sql">查询的Sql语句</param>
        /// <returns></returns>
        public virtual DataTable ExecuteDataTable(string sql)
        {
            IDbCommand command = Session.Connection.CreateCommand();
            command.CommandText = sql;
            using (IDataReader reader = command.ExecuteReader())
            {
                var result = new DataTable();
                DataTable schemaTable = reader.GetSchemaTable();
                for (int i = 0; i < schemaTable.Rows.Count; i++)
                {
                    string columnName = schemaTable.Rows[i][0].ToString();
                    result.Columns.Add(columnName, (Type) schemaTable.Rows[i][12]);
                }

                while (reader.Read())
                {
                    int fieldCount = reader.FieldCount;
                    var values = new Object[fieldCount];
                    for (int i = 0; i < fieldCount; i++)
                    {
                        values[i] = reader.GetValue(i);
                    }
                    result.Rows.Add(values);
                }
                return result;
            }
        }

        /// <summary>
        /// 新增对象实例
        /// </summary>
        /// <param name="obj">对象实例</param>
        public virtual void Add(object obj)
        {
            InvokeObjMethod("SetSysExPro", obj, null);//回调设置系统相关预留属性的值
            Session.Save(obj);
        }

        /// <summary>
        /// 更新对象实例
        /// </summary>
        /// <param name="obj"></param>
        public virtual void Update(object obj)
        {
            InvokeObjMethod("SetSysExPro", obj, null);//回调设置系统相关预留属性的值
            Session.Update(obj);
        }

        /// <summary>
        /// 调回指定方法名称的方法封装
        /// </summary>
        /// <param name="methodName">指定的方法名称</param>
        /// <param name="obj">操作对象实例</param>
        /// <param name="ps">指定方法上应用的参数</param>
        public virtual void InvokeObjMethod(string methodName, object obj, Parameter[] ps)
        {
            if (obj == null || obj.GetType() == null)
                return;
            MethodInfo mi = obj.GetType().GetMethod(methodName);
            if (mi != null)
                mi.Invoke(obj, ps);
        }

        public virtual void SaveOrUpdate(object obj)
        {
            if (obj is BaseEntity)//是继承BaseEntity基类,才会有以下方法
                ((BaseEntity)obj).SetSysExPro();//调用设置系统相关预留属性的值
            Session.SaveOrUpdate(obj);
            if (obj is BaseEntity)//是继承BaseEntity基类,才会有以下方法
                ((BaseEntity) obj).SetSysExProAfterSave();//调用对象保存后需要对系统预留属性进行设置的方法,主要是对OrderId,节点模型进行维护
        }

        /// <summary>
        /// 逻辑删除前的验证,主人是验证对象被其实对象实例引用的情况
        /// </summary>
        /// <param name="obj">待删除的对象</param>
        /// <returns>返回验证过程中不成功的错误描述集合</returns>
        public virtual StringCollection CheckLogicDelete(object obj)
        {
            var sc = new StringCollection();
            if (obj == null)
                sc.Add("待刪除的物件,不能為空,操作無法進行");
            else
            {
                PropertyInfo p = obj.GetType().GetProperty("IsLogicDelete");
                if (p != null)
                {
                    MethodInfo mi = obj.GetType().GetMethod("GetRelateObjectInfo");
                    if (mi != null)
                    {
                        object reValue = mi.Invoke(obj, null);
                        if (reValue != null && reValue is ArrayList)
                        {
                            var alInfo = reValue as ArrayList;
                            for (int i = 0; i < alInfo.Count; i++)
                            {
                                string reLateObjName = ((string[]) alInfo[i])[0];
                                string condition = ((string[]) alInfo[i])[1];
                                string errMsgKeyWord = ((string[]) alInfo[i])[2];
                                string hql = "Select count(*) From " + reLateObjName + " o where " + condition;
                                IList l = Session.CreateQuery(hql).List();
                                if (l != null && l.Count > 0)
                                {
                                    int objAmount = Convert.ToInt32(l[0]);
                                    if (objAmount > 0)
                                        sc.Add("待刪除的物件" + ERR_PRO_NAME_FG + errMsgKeyWord + ERR_PRO_NAME_FG
                                               + ",已經被" + objAmount + "個" + ERR_OBJ_NAME_FG + reLateObjName +
                                               ERR_OBJ_NAME_FG + "對象所引用,操作無法進行");
                                }
                            }
                        }
                    }
                }
            }
            return sc;
        }

        /// <summary>
        /// 设置对象指定属性的值
        /// </summary>
        /// <param name="obj">操作的对象</param>
        /// <param name="proName">指定属性名称</param>
        /// <param name="val">属性值</param>
        /// <returns>是否成功赋值</returns>
        public virtual bool SetObjectPropertyInfo(object obj, string proName, object val)
        {
            PropertyInfo p = obj.GetType().GetProperty(proName);
            if (p != null)
            {
                if (p.PropertyType == val.GetType())
                {
                    p.SetValue(obj, val, null);
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// 设置对象指定属性的值
        /// </summary>
        /// <param name="obj">操作的对象</param>
        /// <param name="proName">指定属性名称</param>
        /// <param name="strProValue">属性值的字符串表现</param>
        /// <returns>是否成功赋值</returns>
        public virtual bool SetObjectPropertyInfo(object obj, string proName, string strProValue)
        {
            PropertyInfo p = obj.GetType().GetProperty(proName);
            if (p != null)
            {
                object val = strProValue;
                if (p.PropertyType == typeof (Boolean))
                    val = Convert.ToBoolean(strProValue);
                else if (p.PropertyType == typeof (DateTime))
                    val = Convert.ToDateTime(strProValue);
                p.SetValue(obj, val, null);
                return true;
            }
            return false;
        }

        /// <summary>
        /// 逻辑删除对象,并返回ErrorMessage
        /// </summary>
        /// <param name="obj">操作对象</param>
        /// <returns></returns>
        public virtual StringCollection LogicDeleteReErrMsg(object obj)
        {
            StringCollection sc = CheckLogicDelete(obj);
            if (sc.Count == 0)
            {
                if (SetObjectPropertyInfo(obj, "IsLogicDelete", false))
                    Session.Save(obj);
            }
            return sc;
        }

        /// <summary>
        /// 复制StringCollection的内容
        /// </summary>
        /// <param name="targetSc">目标字符集合</param>
        /// <param name="sourceSc">源字符集合</param>
        private static void SetDataToStringCollection(ref StringCollection targetSc, ref StringCollection sourceSc)
        {
            for (int i = 0; i < sourceSc.Count; i++)
                targetSc.Add(sourceSc[i]);
        }

        /// <summary>
        /// 逻辑删除对象
        /// </summary>
        /// <param name="selectKeyValues">操作对象的ID集合</param>
        /// <param name="keyProType">关键属性类型</param>
        /// <param name="classType">对象类型</param>
        /// <returns>处理过程中的错误信息</returns>
        public virtual StringCollection LogicDeleteReErrMsg(string selectKeyValues, Type keyProType, Type classType)
        {
            var sc = new StringCollection();
            if (selectKeyValues == null || selectKeyValues.Length == 0)
                return sc;
            string[] ss = selectKeyValues.Split(',');
            foreach (string str in ss)
            {
                object obj = null;
                object objId = str;
                if (keyProType == typeof (Guid))
                    objId = (new Guid(str));

                obj = Session.Load(classType, objId);
                if (obj != null)
                {
                    StringCollection sourceSc = LogicDeleteReErrMsg(obj);
                    SetDataToStringCollection(ref sc, ref sourceSc);
                }
            }
            return sc;
        }

        /// <summary>
        /// 彻底删除对象
        /// </summary>
        /// <param name="obj"></param>
        public virtual void Delete(object obj)
        {
            Session.Delete(obj);
        }

        /// <summary>
        /// 彻底删除对象
        /// </summary>
        /// <param name="selectKeyValues">所选对象指定属性值集合</param>
        /// <param name="keyProType">属性类型</param>
        /// <param name="classType">对象类型</param>
        public virtual void Delete(string selectKeyValues, Type keyProType, Type classType)
        {
            if (string.IsNullOrEmpty(selectKeyValues))
                return;
            string[] ss = selectKeyValues.Split(',');
            foreach (string str in ss)
            {
                object obj = null;
                object objId = str;
                if (keyProType == typeof (Guid))
                    objId = (new Guid(str));

                obj = Session.Load(classType, objId);
                if (obj != null)
                    Session.Delete(obj);
            }
        }


        /// <summary>
        /// 通过Sql获取指定查询的数据集
        /// </summary>
        /// <param name="sql">Sql查询语句</param>
        /// <returns>数据集</returns>
        public virtual DataTable GetDataTableBySql(string sql)
        {
            DataTable dt = null;
            var sqlHlp = new SqlHelper();
            DataSet ds = sqlHlp.ExecuteDataSet(Session, sql);
            if (ds != null && ds.Tables.Count > 0)
                dt = ds.Tables[0];
            return dt;
        }

        /// <summary>
        /// 通过Sql获取指定查询的数据集
        /// </summary>
        /// <param name="sql">Sql查询语句</param>
        /// <returns>数据集</returns>
        public virtual DataSet GetDataSetBySql(string sql)
        {
            var sqlHlp = new SqlHelper();
            DataSet ds = sqlHlp.ExecuteDataSet(Session, sql);
            return ds;
        }

        /// <summary>
        /// 彻底删除时间进行的验证,主要是验证对象是否被其它对象引用
        /// </summary>
        /// <param name="obj">待删除对象</param>
        /// <returns>验证过程中带出的消息</returns>
        public virtual StringCollection CheckDelete(object obj)
        {
            var sc = new StringCollection();
            if (obj == null)
                sc.Add("待刪除的物件,不能為空,操作無法進行");
            else
            {
                PropertyInfo p = obj.GetType().GetProperty("IsLogicDelete");
                if (p != null)
                {
                    MethodInfo mi = obj.GetType().GetMethod("GetRelateObjectInfo");//GetRelateObjectInfo方法中说明待删除的对象与其它对象的依赖性
                    if (mi != null)
                    {
                        object reValue = mi.Invoke(obj, null);
                        if (reValue != null && reValue is ArrayList)
                        {
                            var alInfo = reValue as ArrayList;
                            for (int i = 0; i < alInfo.Count; i++)
                            {
                                string reLateObjName = ((string[])alInfo[i])[0];
                                string condition = ((string[])alInfo[i])[1];
                                string errMsgKeyWord = ((string[])alInfo[i])[2];
                                string hql = "Select count(*) From " + reLateObjName + " o where " + condition;
                                IList l = Session.CreateQuery(hql).List();
                                if (l != null && l.Count > 0)
                                {
                                    int objAmount = Convert.ToInt32(l[0]);
                                    if (objAmount > 0)
                                        sc.Add("待刪除的" + ERR_OBJ_NAME_FG + obj.GetType().Name + ERR_OBJ_NAME_FG + ",值為:[ " + errMsgKeyWord
                                               + " ],已經被" + objAmount + "個[" + ERR_OBJ_NAME_FG + reLateObjName +
                                               ERR_OBJ_NAME_FG + "]對象所引用,操作無法進行");
                                }
                            }
                        }
                    }
                }
            }
            return sc;
        }

        /// <summary>
        /// 生成导入批次号
        /// </summary>
        /// <returns></returns>
        public virtual string GetImportNum()
        {
            return DateTime.Now.ToString("yyyyMMddHHmmssffff");
        }

        /// <summary>
        /// 获取对象属性值
        /// </summary>
        /// <param name="obj">操作的对象</param>
        /// <param name="proName">指定的属性名称</param>
        /// <returns>属性的值</returns>
        public virtual object GetObjectProValue(object obj, string proName)
        {
            object val = null;
            PropertyInfo p = obj.GetType().GetProperty(proName);
            if (p != null)
            {
                p.GetValue(obj, null);
            }
            return val;
        }

        /// <summary>
        /// 设置对象的导入批次号
        /// </summary>
        /// <param name="obj">操作的对象</param>
        public virtual void SetImportNum(object obj)
        {
            if (obj.GetType().GetProperty("Id") != null)
            {
                object objIdobj = GetObjectProValue(obj, "Id");
                if (objIdobj == null || (objIdobj is Guid && ((Guid) objIdobj).Equals(Guid.Empty)))
                {
                    SetObjectPropertyInfo(obj, "ImportNum", GetImportNum());
                }
            }
        }

        /// <summary>
        /// 逻辑删除对象
        /// </summary>
        /// <param name="obj">操作对象</param>
        /// <returns>是否成功</returns>
        public virtual bool LogicDelete(object obj)
        {
            return DeleteReErrMsg(true, obj).Count == 0;
        }

        public virtual StringCollection DeleteReErrMsg(bool isLogicDelete, object obj)
        {
            StringCollection sc = CheckDelete(obj);//逻辑删除前验证
            if (sc.Count == 0)
            {
                if (isLogicDelete)
                {
                    if (SetObjectPropertyInfo(obj, "IsLogicDelete", true))
                        Session.Save(obj);
                }
                else
                {
                    Delete(obj);
                }
            }
            return sc;
        }

        /// <summary>
        /// 把对象从逻辑删除状态还原到正常状态
        /// </summary>
        /// <param name="obj">操作的对象</param>
        public virtual void RevertObject(object obj)
        {
            if (SetObjectPropertyInfo(obj, "IsLogicDelete", false))
                Session.Save(obj);
        }

        /// <summary>
        /// 对象存在性操作的封装(还原,逻辑删除,物理删除)
        /// </summary>
        /// <param name="OperateName">操作类型名称(还原,逻辑删除,物理删除)</param>
        /// <param name="selectKeyValues">对象ID集合</param>
        /// <param name="keyProType">关键属性类型</param>
        /// <param name="classType">对象类型</param>
        /// <returns></returns>
        public virtual StringCollection OperateTheObject(string OperateName, string selectKeyValues, Type keyProType,
                                                         Type classType)
        {
            var sc = new StringCollection();
            if (string.IsNullOrEmpty(selectKeyValues))
                return sc;
            string[] ss = selectKeyValues.Split(',');
            foreach (string str in ss)
            {
                object obj = null;
                object objId = str;
                if (keyProType == typeof (Guid))
                    objId = (new Guid(str));

                obj = Session.Load(classType, objId);
                if (obj != null)
                {
                    var sourceSc = new StringCollection();
                    if (OperateName == REVERT)
                        RevertObject(obj);
                    else if (OperateName == LOGIC_DELETE)
                        sourceSc = DeleteReErrMsg(true, obj);
                    else if (OperateName == REAL_DELETE)
                        sourceSc = DeleteReErrMsg(false, obj);
                    SetDataToStringCollection(ref sc, ref sourceSc);
                }
            }
            return sc;
        }

        /// <summary>
        /// 批量删除对象
        /// </summary>
        /// <param name="isLogicDelete">是否进行逻辑删除</param>
        /// <param name="selectKeyValues">对象关键属性值的集合</param>
        /// <param name="keyProType">对象关键属性类型</param>
        /// <param name="classType">对象类型</param>
        /// <returns>执行过程中带出的消息</returns>
        public virtual StringCollection DeleteReErrMsg(bool isLogicDelete, string selectKeyValues, Type keyProType,
                                                       Type classType)
        {
            var sc = new StringCollection();
            if (string.IsNullOrEmpty(selectKeyValues))
                return sc;

            var sourceSc = new StringCollection();
            if (isLogicDelete)
                sourceSc = OperateTheObject(LOGIC_DELETE, selectKeyValues, keyProType, classType);
            else
                sourceSc = OperateTheObject(REAL_DELETE, selectKeyValues, keyProType, classType);
            SetDataToStringCollection(ref sc, ref sourceSc);
            return sc;
        }

        /// <summary>
        /// 批量删除对象集合
        /// </summary>
        /// <param name="className">对象类型名称</param>
        /// <param name="queryProName">对象查询过滤的属性名称</param>
        /// <param name="queryProValues">对象查询过滤的属性值的集合</param>
        public virtual void DeleteObjectsByKeyValues(string className, string queryProName,
                                                     string queryProValues)
        {
            DeleteObjectsByKeyValues(className, "", queryProName, queryProValues);
        }

        /// <summary>
        /// 批量删除对象集合
        /// </summary>
        /// <param name="className">对象类型名称</param>
        /// <param name="typeName">对象类别名称</param>
        /// <param name="queryProName">对象查询过滤的属性名称</param>
        /// <param name="queryProValues">对象查询过滤的属性值的集合</param>
        public virtual void DeleteObjectsByKeyValues(string className, string typeName, string queryProName,
                                                     string queryProValues)
        {
            if (queryProValues != null && queryProValues.Length > 0)
            {
                string[] ss = queryProValues.Split(',');
                if (ss != null && ss.Length > 0)
                {
                    var sc = new StringCollection();
                    foreach (string str in ss)
                    {
                        if (!sc.Contains(str))
                            sc.Add(str);
                    }
                    if (sc.Count > 0)
                        DeleteObjectsByKeyValues(className, typeName, queryProName, sc);
                }
            }
        }

        /// <summary>
        /// 批量删除对象集合
        /// </summary>
        /// <param name="className">对象类型名称</param>
        /// <param name="queryProName">对象查询过滤的属性名称</param>
        /// <param name="queryProValues">对象查询过滤的属性值的集合</param>
        public virtual void DeleteObjectsByKeyValues(string className, string queryProName,
                                                     StringCollection queryProValues)
        {
            DeleteObjectsByKeyValues(className, "", queryProName, queryProValues);
        }

        /// <summary>
        /// 批量删除对象集合
        /// </summary>
        /// <param name="className">对象类型名称</param>
        /// <param name="typeName">对象类别名称</param>
        /// <param name="queryProName">对象查询过滤的属性名称</param>
        /// <param name="queryProValues">对象查询过滤的属性值的集合</param>
        public virtual void DeleteObjectsByKeyValues(string className, string typeName, string queryProName,
                                                     StringCollection queryProValues)
        {
            if (queryProValues != null && queryProValues.Count > 0)
            {
                string strHeadHql = "From " + className + " o where ";
                if (!String.IsNullOrEmpty(typeName))
                {
                    strHeadHql += "(o.TypeName='" + typeName + "') and ";
                }
                strHeadHql += "(";
                var sb = new StringBuilder(strHeadHql);
                bool notFirst = false;
                for (int i = 0; i < queryProValues.Count; i++)
                {
                    if (notFirst)
                    {
                        sb.Append(" or o." + queryProName + "='");
                    }
                    else
                    {
                        sb.Append("o." + queryProName + "='");
                        notFirst = true;
                    }
                    sb.Append(queryProValues[i]);
                    sb.Append("'");

                    if (i%100 == 0 || i == (queryProValues.Count - 1))
                    {
                        sb.Append(") ");
                        Session.Delete(sb.ToString());
                        sb = new StringBuilder(strHeadHql);
                        notFirst = false;
                    }
                }
            }
        }

        /// <summary>
        /// 批量获取对象
        /// </summary>
        /// <param name="className">对象类型名称</param>
        /// <param name="typeName">对象类别名称(业务二级分支)</param>
        /// <param name="keyProName">作为Key键值的对象属性名称(需要是唯一)</param>
        /// <param name="queryProName">作为查询过滤的属性名称</param>
        /// <param name="queryProValues">作为查询过滤的属性值</param>
        /// <returns>对象集合键值对[Key=KeyProName,Value=对象实例]</returns>
        public virtual NameObjectDictionary GetObjectsByKeyValues(string className, string typeName, string keyProName,
                                                                  string queryProName,
                                                                  StringCollection queryProValues)
        {
            return GetObjectsByKeyValues(className, typeName, keyProName, queryProName, queryProValues, null);
        }

        /// <summary>
        /// 批量获取对象
        /// </summary>
        /// <param name="className">对象类型名称</param>
        /// <param name="typeName">对象类别名称(业务二级分支)</param>
        /// <param name="keyProName">作为Key键值的对象属性名称(需要是唯一)</param>
        /// <param name="queryProName">作为查询过滤的属性名称</param>
        /// <param name="queryProValues">作为查询过滤的属性值</param>
        /// <param name="exCondition">附加HQL查询条件</param>
        /// <returns>对象集合键值对[Key=KeyProName,Value=对象实例]</returns>
        public virtual NameObjectDictionary GetObjectsByKeyValues(string className, string typeName, string keyProName,
                                                                  string queryProName,
                                                                  StringCollection queryProValues, string exCondition)
        {
            if (!string.IsNullOrEmpty(keyProName) && queryProValues != null && queryProValues.Count > 0)
            {
                string strHeadHql = "From " + className + " o where ";
                if (!String.IsNullOrEmpty(typeName))
                {
                    strHeadHql += "(o.TypeName='" + typeName + "') and ";
                }
                if (!String.IsNullOrEmpty(exCondition))
                    strHeadHql += " (" + exCondition + ") and ";
                strHeadHql += "(";
                var nbd = new NameObjectDictionary();
                var sb = new StringBuilder(strHeadHql);
                bool notFirst = false;
                for (int i = 0; i < queryProValues.Count; i++)
                {
                    if (notFirst)
                    {
                        sb.Append(" or o." + queryProName + "='");
                    }
                    else
                    {
                        sb.Append("o." + queryProName + "='");
                        notFirst = true;
                    }
                    sb.Append(queryProValues[i]);
                    sb.Append("'");

                    if (i%100 == 0 || i == (queryProValues.Count - 1))//分段查询,每100个条件,发一你HQL,不然HQL太长,不能进行解析
                    {
                        sb.Append(") ");
                        IList list = Session.CreateQuery(sb.ToString()).List();

                        foreach (object obj in list)
                        {
                            string strProName1 = keyProName;
                            string strProName2 = "";
                            string[] ss = keyProName.Split('.');
                            if (ss.Length == 2)
                            {
                                strProName1 = ss[0];
                                strProName2 = ss[1];
                            }
                            PropertyInfo pi1 = obj.GetType().GetProperty(strProName1);
                            object objVal1 = pi1.GetValue(obj, null);
                            object objKey = objVal1;

                            if (strProName2.Length > 0)
                            {
                                PropertyInfo pi2 = objVal1.GetType().GetProperty(strProName2);
                                object objVal2 = pi2.GetValue(objVal1, null);
                                objKey = objVal2;
                            }
                            if (objKey != null && (objKey is String || objKey is Guid))
                            {
                                string strVal = objKey.ToString();
                                nbd[strVal] = obj;
                            }
                        }
                        sb = new StringBuilder(strHeadHql);
                        notFirst = false;
                    }
                }


                return nbd;
            }
            else
            {
                return new NameObjectDictionary();
            }
        }

        /// <summary>
        /// 批量获取对象
        /// </summary>
        /// <param name="className">对象类型名称</param>
        /// <param name="keyProName">作为Key键值的对象属性名称(需要是唯一),同时也是用作查询过滤的属性</param>
        /// <param name="keyValues">作为查询过滤的属性值</param>
        /// <returns>对象集合键值对[Key=KeyProName,Value=对象实例]</returns>
        public virtual NameObjectDictionary GetObjectsByKeyValues(string className, string keyProName,
                                                                  StringCollection keyValues)
        {
            return GetObjectsByKeyValues(className, keyProName, keyProName, keyValues, null);
        }

        /// <summary>
        /// 批量获取对象
        /// </summary>
        /// <param name="className">对象类型名称</param>
        /// <param name="keyProName">作为Key键值的对象属性名称(需要是唯一),同时也是用作查询过滤的属性</param>
        /// <param name="keyValues">作为查询过滤的属性值</param>
        /// <param name="exCondition">附加HQL查询条件</param>
        /// <returns>对象集合键值对[Key=KeyProName,Value=对象实例]</returns>
        public virtual NameObjectDictionary GetObjectsByKeyValues(string className, string keyProName,
                                                                  StringCollection keyValues, string exCondition)
        {
            return GetObjectsByKeyValues(className, keyProName, keyProName, keyValues, exCondition);
        }

        /// <summary>
        /// 批量获取对象
        /// </summary>
        /// <param name="className">对象类型名称</param>
        /// <param name="keyProName">作为Key键值的对象属性名称(需要是唯一)</param>
        /// <param name="queryProName">作为查询过滤的属性名称</param>
        /// <param name="queryProValues">作为查询过滤的属性值</param>
        /// <returns>对象集合键值对[Key=KeyProName,Value=对象实例]</returns>
        public virtual NameObjectDictionary GetObjectsByKeyValues(string className, string keyProName,
                                                                  string queryProName,
                                                                  StringCollection queryProValues)
        {
            return GetObjectsByKeyValues(className, "", keyProName, queryProName, queryProValues, null);
        }

        /// <summary>
        /// 批量获取对象
        /// </summary>
        /// <param name="className">对象类型名称</param>
        /// <param name="keyProName">作为Key键值的对象属性名称(需要是唯一)</param>
        /// <param name="queryProName">作为查询过滤的属性名称</param>
        /// <param name="queryProValues">作为查询过滤的属性值</param>
        /// <param name="exCondition">附加HQL查询条件</param>
        /// <returns>对象集合键值对[Key=KeyProName,Value=对象实例]</returns>
        public virtual NameObjectDictionary GetObjectsByKeyValues(string className, string keyProName,
                                                                  string queryProName,
                                                                  StringCollection queryProValues, string exCondition)
        {
            return GetObjectsByKeyValues(className, "", keyProName, queryProName, queryProValues, exCondition);
        }
    }
}
